/*
 * @Author: xiaosihan
 * @Date: 2021-04-10 23:13:04
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-11-07 16:38:07
 */


import Btn1 from "@components/btn1/Btn1";
import globalStore from "@globalStore";
import ReactMixinComponent from "@ReactMixinComponent";
import { Switch } from "antd";
import _ from "lodash";
import * as React from "react";
import { Route, Switch as RouteSwitch } from "react-router-dom";
import * as THREE from "three";
import { AmbientLight, AxesHelper, DirectionalLight, GridHelper, Group3D, HemisphereLight, Object3D, Plane, PointLight, Renderer, SkyBox, SpotLight } from "xsh-react-three";
import ExtrudeMeshDemo from "./components/ExtrudeMeshDemo/ExtrudeMeshDemo";
import FPSDemo from "./components/FPSDemo/FPSDemo";
import InstancedMeshDemo from "./components/InstancedMeshDemo/InstancedMeshDemo";
import LineDemo from "./components/LineDemo/LineDemo";
import MeshDemo from "./components/MeshDemo/MeshDemo";
import MyControllerStore from "./components/MyController/MyControllerStore";
import { ControlType } from "./components/MyController/type";
import PointsDemo from "./components/PointsDemo/PointsDemo";
import TextDemo from "./components/TextDemo/TextDemo";
import XRTNav from "./components/XRTNav/XRTNav";
import { XRTDemoRouter } from "./type";
import styles from "./XshReactThreeDemo.less";
import { mousePosition } from "./XshReactThreeDemoStore";

interface Props { }

interface State {
    dev: boolean;
    enableDamping: boolean;
    autoRotate: boolean;
    type: ControlType
}

export default class XshReactThreeDemo extends ReactMixinComponent<Props, State> {
    constructor(props: Props) {
        super(props);
        window["THREE"] = THREE;
    }

    state: State = {
        dev: globalStore.dev,
        enableDamping: MyControllerStore.enableDamping,
        autoRotate: MyControllerStore.autoRotate,
        type: MyControllerStore.type
    }

    componentDidMount() {
        // 监听全局状态
        this.mixin_autorun(() => {
            const { dev } = globalStore;
            const { enableDamping, autoRotate, type } = MyControllerStore;
            this.setState({
                dev,
                enableDamping,
                autoRotate,
                type
            });
        });
    }

    render() {


        const { dev, enableDamping, autoRotate, type } = this.state;

        return (
            <div className={styles.XshReactThreeDemo}>

                {/* 导航按钮 */}
                <XRTNav />

                <div className={styles.btns} >

                    <Btn1 onClick={() => {
                        MyControllerStore.initTime = Number(_.uniqueId());
                        MyControllerStore.position = { x: 0, y: 15, z: 30 };
                        MyControllerStore.center = { x: 2, y: 0, z: 0 };
                    }} >视角1</Btn1>

                    <Btn1 onClick={() => {
                        MyControllerStore.initTime = Number(_.uniqueId());
                        MyControllerStore.position = { x: 0, y: 30, z: 15 };
                        MyControllerStore.center = { x: 0, y: 0, z: 0 };
                    }} >视角2</Btn1>

                    <Btn1 onClick={() => {
                        MyControllerStore.initTime = Number(_.uniqueId());
                        MyControllerStore.position = { x: 15, y: 15, z: 15 };
                        MyControllerStore.center = { x: -2, y: 0, z: 0 };
                    }} >视角3</Btn1>

                    <Btn1
                        onClick={() => {
                            if (type === ControlType.MAP) {
                                MyControllerStore.type = ControlType.ORBIT;
                            } else {
                                MyControllerStore.type = ControlType.MAP;
                            }
                        }}>
                        {`${type === ControlType.MAP ? "地图" : "轨道"}控制器`}
                    </Btn1>

                    <div>
                        惯性 :
                        <Switch
                            checked={enableDamping}
                            onChange={dev => {
                                MyControllerStore.enableDamping = !MyControllerStore.enableDamping;
                            }}
                        />
                    </div>

                    <div>
                        自动旋转 :
                        <Switch
                            checked={autoRotate}
                            onChange={dev => {
                                MyControllerStore.autoRotate = !MyControllerStore.autoRotate;
                            }}
                        />
                    </div>

                </div>

                <Renderer
                    dev={dev}
                    className={styles.renderer}
                    ref={r => {
                        window.renderer = r;
                    }}
                    onResize={(width, height) => {
                    }}
                    onStart={(url, loaded, total) => {
                        // console.log("开始加载");
                        // 这个方法执行在 componentDidMount 之前
                    }}
                    onLoad={() => {
                        // console.log("加载完成");
                    }}
                    onProgress={(url, loaded, total) => {
                        // console.log(url, loaded, total);
                    }}
                    onBeforeRender={(renderer, camera, scene) => {
                    }}
                    onAfterRender={(renderer, camera, scene) => {
                    }}
                    needRender={() => true}
                >

                    <Group3D>
                        <RouteSwitch>
                            <Route exact path={[XRTDemoRouter.ROOT, XRTDemoRouter.MESH_DEMO]} component={MeshDemo} />
                            <Route exact path={XRTDemoRouter.LINE_DEMO} component={LineDemo} />
                            <Route exact path={XRTDemoRouter.TEXT_DEMO} component={TextDemo} />
                            <Route exact path={XRTDemoRouter.POINTS_DEMO} component={PointsDemo} />
                            <Route exact path={XRTDemoRouter.INSTANCED_MESH} component={InstancedMeshDemo} />
                            <Route exact path={XRTDemoRouter.FPS_DEMO} component={FPSDemo} />
                            <Route exact path={XRTDemoRouter.EXTRUDEMESH_DEMO} component={ExtrudeMeshDemo} />
                        </RouteSwitch>
                    </Group3D>

                    {/* 一个平面 */}
                    <Plane
                        map=""
                        className="plane"
                        color="#ccc"
                        position={{ x: 0, y: -2, z: 0 }}
                        // rotation={{ x: Math.PI / -2, y: 0, z: 0 }}
                        rotation={(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, object3d: THREE.Object3D) => {
                            return {
                                x: Math.PI / -2,
                                z: object3d.rotation.z + 0.02,
                            }
                        }}
                        scale={{ x: 100, y: 100, z: 1 }}
                        alphaTest={0.1}
                        material="MeshPhongMaterial"
                        castShadow={false}
                        receiveShadow={true}
                        onMousemove={e => {
                            mousePosition.copy(e.point);
                        }}
                    />

                    {/* 天空盒 */}
                    <SkyBox />

                    {/* 网格参考线 */}
                    <GridHelper
                        position={{ x: -0.1, y: -0.1, z: -0.1 }}
                        rotation={{ x: 0, y: 0, z: 0 }}
                        scale={{ x: 1, y: 1, z: 1 }}
                        lookAt={undefined}
                    />

                    <AxesHelper length={50} />

                    <Group3D
                        position={{ y: 10 }}
                        rotation={(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, object3d: Object3D) => {
                            return {
                                y: object3d.rotation.y + 0.05,
                            }
                        }}
                    >
                        <PointLight
                            duration={5000}
                            color={"#fff"}
                            intensity={0.2}
                            castShadow={true}
                            position={{ x: 5, z: 0 }}
                        />
                    </Group3D>

                    {/* 平行光 */}
                    <DirectionalLight
                        color={"#fff"}
                        position={{ x: 0, y: 10, z: -10 }}
                        rotation={{ x: Math.PI / 4, y: 0, z: 0 }}
                        castShadow={true}
                        intensity={0.2}
                        shadowResolution={1024}
                        shadowSize={20}
                    />

                    {/* 环境光 */}
                    <AmbientLight
                        color="#fff"
                        intensity={0.2}
                        position={{ y: 17 }}
                    />

                    <SpotLight
                        position={{ x: 0, y: 10, z: 0 }}
                        castShadow={true}
                        shadowResolution={1024}
                        intensity={0.5}
                        penumbra={0}
                        angle={Math.PI / 180 * 10}
                        color="#f00"
                        // lookAt={{ x: 5, y: 0, z: 12 }}
                        lookAt={(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, object3d: THREE.Object3D) => {
                            return mousePosition
                        }}
                    />

                    <HemisphereLight
                        intensity={0.1}
                        position={{ x: 0, y: 15, z: 0 }}
                    />

                </Renderer>
            </div >
        )
    }
}